/**
 * Copyright (C) 2010-2016 eBusiness Information, Excilys Group
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed To in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.ohosannotations.internal.model;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;

/**
 * AnnotationElementsHolder
 *
 * @since 2021-07-20
 */
public class AnnotationElementsHolder implements AnnotationElements {
    private final Map<String, Set<? extends Element>> rootAnnotatedElementsByAnnotation = new HashMap<>();
    private final Map<String, Set<AnnotatedAndRootElements>> ancestorAnnotatedElementsByAnnotation = new HashMap<>();

    /**
     * putRootAnnotatedElements
     *
     * @param annotationName 注解名字
     * @param annotatedElements 注解元素 集合
     */
    public void putRootAnnotatedElements(String annotationName, Set<? extends Element> annotatedElements) {
        rootAnnotatedElementsByAnnotation.put(annotationName, annotatedElements);
    }

    /**
     * putAncestorAnnotatedElement
     *
     * @param annotationName 注解名字
     * @param annotatedElement 元素
     * @param rootTypeElement 类型元素
     */
    public void putAncestorAnnotatedElement(String annotationName,
        Element annotatedElement, TypeElement rootTypeElement) {
        Set<AnnotatedAndRootElements> set = ancestorAnnotatedElementsByAnnotation.get(annotationName);
        if (set == null) {
            set = new LinkedHashSet<>();
            ancestorAnnotatedElementsByAnnotation.put(annotationName, set);
        }
        set.add(new AnnotatedAndRootElements(annotatedElement, rootTypeElement));
    }

    @Override
    public Set<AnnotatedAndRootElements> getAncestorAnnotatedElements(String annotationName) {
        Set<AnnotatedAndRootElements> set = ancestorAnnotatedElementsByAnnotation.get(annotationName);
        if (set != null) {
            return set;
        } else {
            return Collections.emptySet();
        }
    }

    @Override
    public Set<? extends Element> getRootAnnotatedElements(String annotationName) {
        Set<? extends Element> set = rootAnnotatedElementsByAnnotation.get(annotationName);
        if (set != null) {
            return set;
        } else {
            return Collections.emptySet();
        }
    }

    @Override
    public Set<Element> getAllElements() {
        Set<Element> allElements = new HashSet<>();

        for (Set<? extends Element> annotatedElements : rootAnnotatedElementsByAnnotation.values()) {
            allElements.addAll(annotatedElements);
        }

        return allElements;
    }

    /**
     * validatingHolder
     *
     * @return holder
     */
    public AnnotationElementsHolder validatingHolder() {
        AnnotationElementsHolder holder = new AnnotationElementsHolder();
        holder.ancestorAnnotatedElementsByAnnotation.putAll(ancestorAnnotatedElementsByAnnotation);
        return holder;
    }

}
